home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Meeting Pearls 1
/
Meeting Pearls Vol 1 (1994).iso
/
amok98-106
/
amok103
/
identifiedtypes
/
identifiedtypes.dok
< prev
next >
Wrap
Text File
|
1993-12-05
|
8KB
|
189 lines
(****************************************************************************
:Program. IdentifiedTypes.mod
:Contents. module to handle type-ids for storing data in files, ....
:Author. Richard Günther [gvm]
:Address. HeilbronnerStr.267, 72760 Reutlingen
:Phone. 07121/66432
:Copyright. PublicDomain
:Language. Oberon2
:Translator. AmigaOberon v3.00d
:Imports. none
:History. V0.9 [gvm] 04-Oct-93 first implementation
:History. V1.0 [gvm] 31-Oct-93 fixed bugs
:Bugs. none known, won't perhaps work with future Compiler-Versions!
****************************************************************************)
COPYRIGHT:
Dieses Modul darf ohne Einschränkungen in nicht kommerziellen
(Shareware ist kommerziell) Programmen verwendet werden.
Für anderweitige Verwendung ist meine schriftliche Zustimmung
nötig, setzen Sie sich bitte mit mir in Verbindung.
Dieses Modul darf nur in seinem vollen Umfang (Dokumentation,
Quellcode) und nur zum Selbstkostenpreis (maximal 5 Deutsche Mark)
vertrieben werden.
Ich übernehme keine Garantie für die Fehlerfreiheit dieses Moduls. Die ver-
wendung der Routinen ist auf eigene Gefahr, für eventuelle Schäden an Daten
oder Programmen wird keine Haftung übernommen!
INHALT:
Dieses Modul verwaltet Typen und bietet eine Art Typ-Typ, anhand
dem sich eine Variable identifizieren und reproduzieren kann
(weiterlesen!).
Dadurch werden in eingeschränkter Weise die Funktionen von
Konstruktoren (C++/BorlandPascal(R)) und Metaklassen (Smalltalk)
nachgebildet. Schön wäre es natürlich wenn ich dies nicht durch
umständlichen Code (INLINE..) selbst erledigen müßte, sondern
wenn das Konzept der Konstruktoren
und
Destruktoren sowie
der Metaklassen (in Oberon wohl besser (?) als Typ-Typ zu bezeichnen)
in den Sprachumfang von AmigaOberon aufgenommen würde.
Der Typ-Typ entspräche dem Typdescriptor, dem dann ein eigener,
fest eingebauter Typ spendiert werden müßte, der sich wie ein
Record verhält, also man auf ihn Methoden anwenden darf, sowie
ein oder mehrere benutzerdefinierbare Felder enthält
(für den ID-String).
Ich werde trotzdem daran weiterarbeiten, auch einen Destruktor zu
implementieren (Puh, noch mehr INLINE...).
PROZEDUR-BESCHREIBUNGEN:
Jeder Datentyp, der von den folgenden Möglichkeiten gebrauch machen will,
muß als Erweiterung von IdentifiedTypes.IDENTDesc definiert werden.
IDENTDesc ist wiefolgt definiert:
TYPE IDENT = POINTER TO IDENTDesc;
IDENTDesc = RECORD (BasicTypes.ANYDesc) END;
Mit der Definition eines Typen ist es allerdings nicht getan, Sie müssen
ihre Datentypen IdentifiedTypes bekannt machen. Dies geschieht entweder
mittels der Prozedur AddManualCreateType oder mittels AddAutoCreateType.
AddManualCreateType ist die universellere Routine, sie können Sie auf
alle Typen anwenden. AddAutoCreateType können Sie nur auf solche Typen
anwenden, die in ihrer Struktur nur einen Typ-Descriptor enthalten, d.h.
Records, die innerhalb ihrer Definition Records (nicht Pointer auf Records!)
enthalten, dürfen Sie hier nicht verwenden!!!
Für AddManualCreateType müssen Sie (das ist der Nachteil) eine Prozedur
angeben, die eine Variable des Typs erzeugt (s.u.). AddManualCreateType
benötigen Sie daher auch, wenn es mit der Speicherallozierung für die
Variable nicht getan ist, sondern noch Strukturelemente initialisiert
werden müssen.
PROCEDURE AddManualCreateType(name: ARRAY OF CHAR;
typedesc: SYSTEM.ADDRESS;
creator: CreatorProc
): IDENTManualCreateIdentifier;
Bei
name
geben Sie bitte eine Charakteristische Bezeichnung für den Typ
an, momentan werden die 8 ersten Zeichen berücksichtigt. (Fehlende
Zeichen werden mit Null-Bytes aufgefüllt)
Bei
typedesc
geben Sie bitte den Typ-Descriptor des Typs an (mittels
SYSTEM.TYPEDESC(Typ)).
Bei
creator
geben Sie bitte eine Prozedur der folgenden Form an:
CreatorProc* = PROCEDURE (): IDENT;
Diese Prozedur sollte eine Variable des Typs erzeugen und zurückgeben.
Als Rückgabe erhalten Sie den Pointer auf eine ID-Struktur, wenn er
NIL ist, ist ein Fehler aufgetreten. In der Regel benötigen Sie diesen
Pointer nicht mehr.
PROCEDURE AddAutoCreateType(name: ARRAY OF CHAR;
exampleVar: IDENT
): IDENTAutoCreateIdentifier;
Bei
name
geben Sie bitte eine Charakteristische Bezeichnung für den Typ
an, momentan werden die 8 ersten Zeichen berücksichtigt. (Fehlende
Zeichen werden mit Null-Bytes aufgefüllt)
Bei
exampleVar
geben Sie bitte eine Variable des Typs an.
Als Rückgabe erhalten Sie den Pointer auf eine ID-Struktur, wenn er
NIL ist, ist ein Fehler aufgetreten. In der Regel benötigen Sie diesen
Pointer nicht mehr.
Über die ID-Struktur haben Sie Zugriff auf folgende Methoden:
PROCEDURE (id: IDENTIdentifier) Create(): IDENT;
erzeugt eine Variable des Typs in der Typ-Typ-Variable id.
Zugriff auf die ID-Struktur erhalten Sie auch über
PROCEDURE FindIDENTIdentifier(name: ARRAY OF CHAR): IDENTIdentifier;
Diese Prozedur gibt die zu name gehörige ID-Struktur zurück, sie
entspricht der, die Sie beim Aufruf von AddAuto/ManualCreateType
als Ergebnis erhalten.
Folgende Methoden sind dann für die Variablen der angemeldeten Typen
definiert:
PROCEDURE (var: IDENT) CreateIDENTOfSameType*(): IDENT;
erzeugt eine Variable des gleichen Typs wie var.
PROCEDURE (var: IDENT) Copy*(dest: IDENT);
kopiert die Daten von var nach dest.
Um diese Methode zu benutzen muß für jeden Typ die Methode Copy
wiefolgt definiert werden:
z.B. PROCEDURE (var: Haus) Copy*(dest: IDENT);
BEGIN
var.Copy^(dest); (* <--- Wichtig!!!! *)
IF dest IS Haus THEN
lokale daten kopieren...
END;
END;
PROCEDURE (var: IDENT) Duplicate*(): IDENT;
erstellt eine Kopie von var. Dazu müssen Copy-Methoden definiert
sein (s.o.).
PROCEDURE (t: IDENT) Write*(VAR to: FileSystem.File): BOOLEAN;
schreibt die Daten der Variable t und den bei name angegebenen
Typ-ID-String in die Datei to. Liefert TRUE, wenn alles ok war.
Um diese Methode zu benutzen muß für jeden Typ die Methode Write
wiefolgt definiert werden:
z.B. PROCEDURE (var: Haus) Write*(VAR to: FileSystem.File): BOOLEAN;
BEGIN
RETURN var.Write^(to) AND (* <--- Wichtig!!!! *)
FileSystem.Write(to, ...lokale Daten... );
END;
PROCEDURE (t: IDENT) Read*(VAR from: FileSystem.File): BOOLEAN;
liest die Daten aus from in die Variable t ein. Liefert TRUE, wenn
alles ok war. Um diese Methode zu benutzen muß für jeden Typ die
Methode Read wiefolgt definiert werden:
z.B. PROCEDURE (var: Haus) Read*(VAR from: FileSystem.File): BOOLEAN;
BEGIN
RETURN var.Read^(from) AND (* <--- Wichtig!!!! *)
FileSystem.Read(from, ...lokale Daten... );
(* gleiche Reihenfolge wie bei Write! *)
END;
PROCEDURE ReadNext*(VAR from: FileSystem.File): IDENT;
dies ist wohl die Prozedur, die Sie zum lesen verwenden werden. Sie
liest den nächsten Datensatz aus from aus und liefert einen Pointer
auf die in from abgelegte Struktur.
Wenn ReadNext NIL zurückgibt, ist entweder das Dateiende erreicht,
es trat ein Lesefehler auf, oder ein unbekannter Datensatz folgt.
(Für nähere Fehlerbestimmung interpretieren Sie das Feld from.status)
Ein ausführliches Beispielprogramm finden Sie auf dieser Diskette.
(ein Teil eines CAD-Programms, CadTypen und CadSaveLoad, sowie ein
Testmodul)
Weitere (Un-)Klarheiten können Sie durch die Lektüre des Quelltextes
(man ignoriere die Zahlreichen INLINES...) beseitigen.
Für Fragen und Anregungen stehe ich gerne zur Verfügung.